<template>
  <login-box class="register-box">
    <n-form
      ref="userRegisterFormRef"
      label-placement="left"
      label-width="auto"
      :model="userRegisterForm"
      :rules="userRegisterFormRules"
      size="medium"
      class="flex flex-col items-center"
    >
      <n-form-item path="username" class="w-[300px]">
        <n-input
          v-model:value="userRegisterForm.username"
          placeholder="请输入用户名"
          clearable
          :allow-input="noSideSpace"
          :maxlength="16"
        >
          <template #prefix>
            <n-icon :component="User" />
          </template>
        </n-input>
      </n-form-item>
      <n-form-item path="email" class="w-[300px]">
        <n-input
          v-model:value="userRegisterForm.email"
          placeholder="请输入邮箱地址"
          clearable
          :allow-input="noSideSpace"
          :maxlength="50"
        >
          <template #prefix>
            <svg-icon
              icon="youxiang"
              color="#ccc"
              size="18px"
              class="cursor-pointer"
            />
          </template>
        </n-input>
      </n-form-item>
      <n-form-item label="" path="emailCode">
        <n-input-group class="!w-[300px]">
          <n-input
            v-model:value="userRegisterForm.emailCode"
            placeholder="请输入邮箱验证码"
            :allow-input="noSideSpace"
            clearable
          />
          <n-button
            type="primary"
            ghost
            @click="sendCodeValidate"
            v-if="emailCodeSecond === 0"
            :disabled="!canSendCode"
          >
            发送验证码
          </n-button>
          <n-button type="primary" ghost v-else>
            {{ emailCodeSecond + 's' }}
          </n-button>
        </n-input-group>
      </n-form-item>
      <n-form-item path="password" class="w-[300px]">
        <n-input
          v-model:value="userRegisterForm.password"
          placeholder="请输入密码"
          type="password"
          show-password-on="click"
          :allow-input="noSideSpace"
          :maxlength="20"
        >
          <template #prefix>
            <n-icon :component="Key" />
          </template>
        </n-input>
      </n-form-item>
      <n-form-item path="rePassword" class="w-[300px]">
        <n-input
          v-model:value="userRegisterForm.rePassword"
          placeholder="请再次输入密码"
          type="password"
          show-password-on="click"
          :allow-input="noSideSpace"
          :maxlength="20"
        >
          <template #prefix>
            <n-icon :component="Key" />
          </template>
        </n-input>
      </n-form-item>
      <n-form-item class="w-[300px]">
        <n-button type="primary" @click="handleRegister" class="w-[300px]">
          注册
        </n-button>
      </n-form-item>
    </n-form>

    <n-button quaternary type="info" @click="handleToLogin">
      已有账号登录
    </n-button>

    <n-modal v-model:show="dialogs.sendMsg" to=".register-box">
      <PicValidCode
        @on-finish="handleFinish"
        @visible-change="handleVisibleChange"
      ></PicValidCode>
    </n-modal>
  </login-box>
</template>

<script setup lang="ts">
import { useMessage, useDialog } from 'naive-ui'
import type { FormInst } from 'naive-ui'
import { userRegister, validateUserProfile } from '@/api/user'
import { User, Key } from '@vicons/fa'
import { LOGIN_REMEBER } from '@/constants/user'
import { noSideSpace } from '@/utils'
import { load } from '@/utils/loading'
import { setItem } from '@/utils/storage'
import aes from '@/utils/aes'
import { userSchema } from '@/utils/rule'
import { useSendCode } from '@/hooks/useSendCode'
import LoginBox from './LoginBox.vue'

const { sendCode, emailCodeSecond } = useSendCode()
const emits = defineEmits<{
  (e: 'changeCurModel', value: 'register' | 'login'): void
}>()

const message = useMessage()
const dialog = useDialog()

// ------------------用户登录相关逻辑---------------------
const userRegisterForm = reactive({
  username: '',
  password: '',
  email: '',
  emailCode: '',
  rePassword: ''
})

const canSendCode = ref(false)
const userRegisterFormRules = reactive({
  username: [
    ...userSchema.username,
    {
      // 异步校验用户名是否被占用
      message: '用户名被占用',
      trigger: 'blur',
      validator: (rule: any, value: string) => {
        return new Promise<void>((resolve, reject) => {
          validateUserProfile({
            username: value
          })
            .then(() => {
              resolve()
            })
            .catch(() => {
              reject('用户名被占用')
            })
        })
      }
    }
  ],
  email: [
    ...userSchema.email,
    {
      // 异步校验用户名是否被占用
      message: '邮箱被占用',
      trigger: 'blur',
      validator: (rule: any, value: string) => {
        return new Promise<void>((resolve, reject) => {
          validateUserProfile({
            email: value
          })
            .then(() => {
              resolve()
              canSendCode.value = true
            })
            .catch(() => {
              reject('邮箱被占用')
              canSendCode.value = false
            })
        })
      }
    }
  ],
  emailCode: userSchema.emailCode,
  password: userSchema.password,
  rePassword: [
    {
      required: true,
      message: '请再次输入密码',
      trigger: ['blur']
    },
    {
      validator: (rule: any, value: string) => {
        return value === userRegisterForm.password
      },
      message: '两次输入密码不一致',
      trigger: ['blur']
    }
  ]
})

const userRegisterFormRef = ref<FormInst | null>(null)

const dialogs = reactive({
  sendMsg: false
})

const handleVisibleChange = (value: boolean) => {
  dialogs.sendMsg = value
}

const handleFinish = (picCode: string) => {
  // 进行发送验证码的操作，带上一个图片验证码值
  sendCode('register', 'email', userRegisterForm.email, picCode)
  dialogs.sendMsg = false
}

// 发送验证码按钮被点击
const sendCodeValidate = () => {
  dialogs.sendMsg = true
}

const handleRegister = () => {
  userRegisterFormRef.value?.validate((errors) => {
    if (!errors) {
      load.show()
      userRegister({
        username: userRegisterForm.username,
        password: userRegisterForm.password,
        email: userRegisterForm.email,
        code: userRegisterForm.emailCode
      })
        .then(() => {
          message.success('注册成功')
          setItem(LOGIN_REMEBER, {
            username: aes.encrypt(userRegisterForm.username),
            password: aes.encrypt(userRegisterForm.password)
          })
          handleToLogin()
        })
        .catch(console.error)
        .finally(() => {
          load.hide()
        })
    } else {
      console.log(errors)
      message.error('填写信息有误')
    }
  })
}

const handleToLogin = () => {
  emits('changeCurModel', 'login')
}
</script>

<style scoped lang="scss"></style>
